package state.component;


import state.GameConstants;
import state.Graphics;
import state.Image;
import state.Manager;
import state.Sprite;
import state.font.ImageText;
import state.util.ImageUtil;

public class Checkbox extends Component {
  private final int DX = 5;
  private final int DY = 3;
  
  private static Image checkedImage;
  private static Image uncheckedImage;
  
  protected EventListener listener;
  
  private boolean isChecked = false;
  private String label;
  private int textDistance;
  private boolean isDrawLabelFirst = false;
  
  private int componentWidth;
  
  public Checkbox() {
  }
  
  public Checkbox(Manager manager) {
    setManager(manager);
  }
  
  public Checkbox(Manager manager, int x, int y) {
    setManager(manager);
    setPosition(x, y);
  }
  
  public Checkbox(Manager manager, EventListener listener, Style style) {
    if (listener != null) {
      setListener(listener);
    }

    if (style != null) {
      setStyle(style);
    }
    setManager(manager);
  }

  public Checkbox(Manager manager, EventListener listener, Style style, int x, int y) {
    this(manager, listener, style);
    setPosition(x, y);
  }

  protected void init() {
    super.init();
    label = "";
    textDistance = 5;
    
    if (checkedImage == null) {
      checkedImage = ImageUtil.getCoreImage("checkbox_checked.png").setStatic(true);
      uncheckedImage = ImageUtil.getCoreImage("checkbox_unchecked.png").setStatic(true);
    }
    height = Math.max(checkedImage.getHeight(), getFont().getHeight()) + DY * 2;
    calculateComponentWidth();
  }
  
  private void calculateComponentWidth() {
    componentWidth = checkedImage.getWidth() + textDistance + getFont().stringWidth(label);
    setWidth(componentWidth + DX * 2 + 1);
  }

  public void draw(Graphics g) {
    if (isFillBackGround()) {
      if (isFocusable() && isFocused) {
        g.setColor(getFocusBgColor());
      } else {
        g.setColor(getBackgroundColor());
      }
      g.fillRect(realX - 1, realY - 1, width, height);
    }
    
    int imageX = realX + DX;
    int textX = realX + checkedImage.getWidth() + textDistance + DX;
    
    if (isDrawLabelFirst) {
      imageX = realX + getFont().stringWidth(label) + textDistance + DX;
      textX = realX + DX;
    }
    
    if (isChecked) {
      g.drawImage(checkedImage, imageX, realY + DY, GameConstants.TOP_LEFT_ANCHOR);
    } else {
      g.drawImage(uncheckedImage, imageX, realY + DY, GameConstants.TOP_LEFT_ANCHOR);
    }
    
    int color = forceGroundColor;
    if (isFocusable() && isFocused) {
      color = focusFgColor;
      if (hasBorder) {
        g.setColor(borderColor);
        g.drawRect(realX, realY, width - 1, height - 1);
      }
    }
    getFont().drawString(g, label, color, textX, realY, GameConstants.TOP_LEFT_ANCHOR);
  }
  
  public Checkbox setListener(EventListener listener) {
    this.listener = listener;
    return this;
  }

  public static void setCheckImage(Image checkedImage) {
    Checkbox.checkedImage = checkedImage;
  }
  
  public static void setUncheckImage(Image uncheckedImage) {
    Checkbox.uncheckedImage = uncheckedImage;
  }
  
  public boolean isChecked() {
    return isChecked;
  }

  public Checkbox setChecked(boolean isChecked) {
    this.isChecked = isChecked;
    return this;
  }
  
  public String getLabel() {
    return label;
  }

  public Checkbox setLabel(String label) {
    this.label = label;
    calculateComponentWidth();
    return this;
  }

  public int getTextDistance() {
    return textDistance;
  }

  public Checkbox setTextDistance(int textDistance) {
    this.textDistance = textDistance;
    calculateComponentWidth();
    return this;
  }

  public boolean isDrawLabelFirst() {
    return isDrawLabelFirst;
  }

  public Checkbox setDrawLabelFirst(boolean isDrawLabelFirst) {
    this.isDrawLabelFirst = isDrawLabelFirst;
    return this;
  }

  public Component setFont(ImageText font) {
    if (font == null) {
      return this;
    }
    height = Math.max(font.getHeight(), height);
    return super.setFont(font);
  }

  public void pointerReleased(Sprite source, int x, int y) {
    setChecked(!isChecked());
    manager.setFocus(this);
  }
}
